home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / libs / hobbes3 / line.asm < prev    next >
Assembly Source File  |  1992-08-17  |  17KB  |  537 lines

  1. include hobbes.inc
  2. include extrn.inc
  3.  
  4.  
  5. .DATA
  6. ; Plane masks for clipping left and right edges of rectangle.
  7. LeftClipPlaneMask       db      00fh,00eh,00ch,008h
  8. RightClipPlaneMask      db      001h,003h,007h,00fh
  9.  
  10. .CODE
  11. ;--------------------------------------------------------------------------
  12. ; void HLine( int X1, int X2, int Y, char COLOR )
  13. ; void HLineClip( int X1, int X2, int Y, char COLOR )
  14. ;
  15.  
  16.         public  _HLineClip
  17. _HLineClip proc
  18. ARG    X1:WORD, X2:WORD, Y:WORD, COLOR:WORD
  19.         push    bp
  20.         mov     bp,sp
  21.         push    ds
  22.         mov     ax,@data
  23.         mov     ds,ax
  24.  
  25.         mov     ax,Y
  26.         cmp     ax,_ClipTop
  27.         jl      @@hlc_exit
  28.         cmp     ax,_ClipBottom
  29.         jg      @@hlc_exit
  30.         mov     ax,X1
  31.         cmp     ax,_ClipRight
  32.         jg      @@hlc_exit
  33.         cmp     ax,_ClipLeft
  34.         jge     @@hlc_1
  35.         mov     ax,_ClipLeft
  36.         mov     X1,ax
  37. @@hlc_1:
  38.         mov     ax,X2
  39.         cmp     ax,_ClipLeft
  40.         jl      @@hlc_exit
  41.         cmp     ax,_ClipRight
  42.         jle     hlc_2
  43.         mov     ax,_ClipRight
  44.         mov     X2,ax
  45.         jmp     short hlc_2
  46. @@hlc_exit:
  47.         pop     ds
  48.         pop     bp
  49.                 ret
  50. _HLineClip      endp
  51.  
  52.         public  _HLine
  53. _HLine  proc    far
  54.         push    bp
  55.         mov     bp,sp
  56.         push    ds
  57.         mov     ax,@data
  58.         mov     ds,ax
  59. hlc_2:
  60.         mov     es,_ModeX_Segment     ; point ES:DI to the left pixel's address
  61.         push    si
  62.         push    di
  63.  
  64.         cld
  65.         mov     di,Y
  66.         shl     di,1
  67.         mov     di,word ptr _RowOffset[di]
  68.         mov     ax,X1
  69.         shr     ax,2            ; X/4 = offset of pixel in scan line
  70.         add     di,ax           ; final offset of pixel in page
  71.         add        di,_Display_Offset
  72.  
  73.         mov     dx,SC_INDEX     ; set the Sequence Controller Index to
  74.         mov     al,MAP_MASK     ;   point to the Map Mask register
  75.         out     dx,al
  76.         inc     dx              ; point DX to the SC Data register
  77.  
  78.         mov     si,X1
  79.         and     si,0003h                        ; look up left edge plane mask
  80.         mov     bh,LeftClipPlaneMask[si]        ;   to clip & put in BH
  81.         mov     si,X2
  82.         and     si,0003h                        ; look up right edge plane
  83.         mov     bl,RightClipPlaneMask[si]       ;   mask to clip & put in BL
  84.  
  85.         mov     cx,X2           ; calculate # of addresses across line
  86.         mov     si,X1
  87.         and     si,not 011b
  88.         sub     cx,si
  89.         shr     cx,2            ; # of addresses across line to draw - 1
  90.         jnz     @@HL_MasksSet   ;  there's more than one byte to draw
  91.         and     bh,bl           ; there's only one byte, so combine the left
  92.                                 ;   and right edge clip masks
  93. @@HL_MasksSet:
  94.         mov     ah,byte ptr COLOR
  95.         mov     al,bh               ; put left-edge clip mask in AL
  96.         out     dx,al               ; set the left-edge plane (clip) mask
  97.         mov     al,ah               ; put color in AL
  98.         stosb                       ; draw the left edge
  99.         dec     cx                  ; count off left edge byte
  100.         js      @@HL_Done             ; that's the only byte
  101.         jz      @@HL_DoRtEdge         ; there are only two bytes
  102.         mov     al,00fh             ; middle addresses are drawn 4 pixels at a pop
  103.         out     dx,al               ; set the middle pixel mask to no clip
  104.         mov     al,ah               ; put color in AL
  105.         shr     cx,1
  106.         rep stosw                   ; draw the middle addresses four pixels apiece
  107.         adc     cx,0
  108.         rep stosb
  109. @@HL_DoRtEdge:
  110.         mov     al,bl               ; put right-edge clip mask in AL
  111.         out     dx,al               ; set the right-edge plane (clip) mask
  112.         mov     al,ah               ; put color in AL
  113.         stosb                       ; draw the right edge
  114. @@HL_Done:
  115.         pop     di                  ; restore caller's register variables
  116.         pop     si
  117.         pop     ds
  118.         pop     bp                  ; restore caller's stack frame
  119.         ret
  120. _HLine  endp
  121.  
  122.  
  123.  
  124.  
  125. ;-----------------------------------------------------------------------
  126. ; void VLine( int X, int Y1, int Y2, char COLOR )
  127. ; void VLineClip( int X, int Y1, int Y2, char COLOR )
  128. ;
  129.         public  _VLineClip
  130. _VLineClip proc
  131. ARG    X:WORD, Y1:WORD, Y2:WORD, COLOR:WORD
  132.         push    bp
  133.         mov     bp,sp
  134.         push    ds
  135.         mov     ax,@data
  136.         mov     ds,ax
  137.  
  138.         mov     ax,X
  139.         cmp     ax,_ClipLeft
  140.         jl      @@vlc_exit
  141.         cmp     ax,_ClipRight
  142.         jg      @@vlc_exit
  143.         mov     ax,Y1
  144.         cmp     ax,_ClipBottom
  145.         jg      @@vlc_exit
  146.         cmp     ax,_ClipTop
  147.         jge     @@vlc_1
  148.         mov     ax,_ClipTop
  149.         mov     Y1,ax
  150. @@vlc_1:
  151.         mov     ax,Y2
  152.         cmp     ax,_ClipTop
  153.         jl      @@vlc_exit
  154.         cmp     ax,_ClipBottom
  155.         jle     vlc_2
  156.         mov     ax,_ClipRight
  157.         mov     Y2,ax
  158.         jmp     short vlc_2
  159. @@vlc_exit:
  160.         pop     ds
  161.         pop     bp
  162.                 ret
  163. _VLineClip      endp
  164.  
  165.         public  _VLine
  166. _VLine  proc    far
  167.         push    bp
  168.         mov     bp,sp
  169.         push    ds
  170.         mov     ax,@data
  171.         mov     ds,ax
  172. vlc_2:
  173.         mov     es,_ModeX_Segment     ; put video segment in ES
  174.  
  175.         mov     cl,byte ptr X   ; set the drawing plane for the vline
  176.         and     cl,011b         ; CL = vline's plane
  177.         mov     ax,0100h+MAP_MASK ; AL = index in SC of Map Mask reg
  178.         shl     ah,cl           ; set only the bit for the vline's plane to 1
  179.         mov     dx,SC_INDEX     ; set the Map Mask to enable only
  180.         out     dx,ax           ;   the vline's plane
  181.  
  182.         mov     bx,Y1           ; compute the starting address of the vline
  183.         shl     bx,1
  184.         mov     bx,word ptr _RowOffset[bx]
  185.         mov     ax,X
  186.         shr     ax,2            ; X/4 = offset of pixel in scan line
  187.         add     bx,ax           ; final offset of pixel in page
  188.         add        bx,_Display_Offset    ; adjust for current page
  189.  
  190.         mov     cx,Y2
  191.         sub     cx,Y1           ; compute number of pixels in line - 1
  192.  
  193.         mov     al,byte ptr COLOR
  194. @@vl_loop:
  195.         mov     es:[bx],al              ; set the current pixel
  196.         add     bx,_Virtual_Width_Addr    ; jump to the pixel below
  197.         dec     cx                      ; decrement the counter
  198.         jge     @@vl_loop               ; loop until less than zero
  199.  
  200.         pop     ds
  201.         pop     bp
  202.         ret
  203. _VLine  endp
  204.  
  205.  
  206.  
  207.  
  208. ;-----------------------------------------------------------------------
  209. ; void HLineR( int X1, int X2, int Y, char COLOR )
  210. ; void HLineClipR( int X1, int X2, int Y, char COLOR )
  211. ;
  212. ;       Draws a horizontal line from (X1, Y) to (X2, Y).
  213. ;       Uses Watcom Parameter passing convention in registers
  214. ;
  215. ;   X1 in AX
  216. ;   X2 in DX
  217. ;   Y in CX
  218. ;   Color in BX
  219.  
  220.         public  _HLineClipR
  221. _HLineClipR proc
  222.         push    ds
  223.         push    @data
  224.         pop     ds
  225.  
  226.         cmp     cx,_ClipTop
  227.         jl      @@hlc_exitR
  228.         cmp     cx,_ClipBottom
  229.         jg      @@hlc_exitR
  230.  
  231.         cmp     ax,_ClipRight
  232.         jg      @@hlc_exitR
  233.         cmp     ax,_ClipLeft
  234.         jge     @@hlc_1R
  235.         mov     ax,_ClipLeft
  236.  
  237. @@hlc_1R:
  238.         cmp     dx,_ClipLeft
  239.         jl      @@hlc_exitR
  240.         cmp     dx,_ClipRight
  241.         jle     hlc_2R
  242.         mov     dx,_ClipRight
  243.         jmp     short hlc_2R
  244. @@hlc_exitR:
  245.         pop     ds
  246.                 ret
  247. _HLineClipR     endp
  248.  
  249.  
  250.         public  _HLineR
  251. _HLineR proc    far
  252.         push    ds
  253.         push    @data
  254.         pop     ds
  255. hlc_2R:
  256.         mov     es,_ModeX_Segment     ; point ES:DI to the left pixel's address
  257.         push    si
  258.         push    di
  259.  
  260.         cld
  261.         mov     di,cx
  262.         shl     di,1
  263.         mov     di,word ptr _RowOffset[di]
  264.         mov     si,ax
  265.         shr     si,2            ; X/4 = offset of pixel in scan line
  266.         add     di,si           ; final offset of pixel in page
  267.         add        di,_Display_Offset    ; adjust for current page
  268.  
  269.         mov     cx,bx
  270.         mov     si,ax
  271.         and     si,0003h                        ; look up left edge plane mask
  272.         mov     bh,LeftClipPlaneMask[si]        ;   to clip & put in BH
  273.         mov     si,dx
  274.         and     si,0003h                        ; look up right edge plane
  275.         mov     bl,RightClipPlaneMask[si]       ;   mask to clip & put in BL
  276.  
  277.         mov     si,ax
  278.         mov     ah,cl           ; Get the Color for later
  279.         mov     cx,dx           ; calculate # of addresses across line
  280. ; DI-~Y,SI-X1,AH-C,CX-X2,BX-mask
  281. ; AL,DX
  282.  
  283.         mov     dx,SC_INDEX     ; set the Sequence Controller Index to
  284.         mov     al,MAP_MASK     ;   point to the Map Mask register
  285.         out     dx,al
  286.         inc     dx              ; point DX to the SC Data register
  287.  
  288.         and     si,not 011b
  289.         sub     cx,si
  290.         shr     cx,2    ; # of addresses across line to draw - 1
  291.         jnz     @@HL_MasksSetR     ;  there's more than one byte to draw
  292.         and     bh,bl   ; there's only one byte, so combine the left
  293.                         ;   and right edge clip masks
  294. @@HL_MasksSetR:
  295.         mov     al,bh   ; put left-edge clip mask in AL
  296.         out     dx,al   ; set the left-edge plane (clip) mask
  297.         mov     al,ah   ; put color in AL
  298.         stosb           ; draw the left edge
  299.         dec     cx      ; count off left edge byte
  300.         js      @@HL_DoneR         ; that's the only byte
  301.         jz      @@HL_DoRtEdgeR     ; there are only two bytes
  302.         mov     al,00fh ; middle addresses are drawn 4 pixels at a pop
  303.         out     dx,al   ; set the middle pixel mask to no clip
  304.         mov     al,ah   ; put color in AL
  305.         shr     cx,1
  306.         rep stosw       ; draw the middle addresses four pixels apiece
  307.         adc     cx,0
  308.         rep stosb
  309. @@HL_DoRtEdgeR:
  310.         mov     al,bl   ; put right-edge clip mask in AL
  311.         out     dx,al   ; set the right-edge plane (clip) mask
  312.         mov     al,ah   ; put color in AL
  313.         stosb           ; draw the right edge
  314. @@HL_DoneR:
  315.         pop     di
  316.         pop     si
  317.         pop     ds
  318.         ret
  319. _HLineR  endp
  320.  
  321.  
  322.  
  323.  
  324. ;-----------------------------------------------------------------------
  325. ; void Line( int X1, int Y1, int X2, int Y2, int COLOR )
  326.  
  327.  
  328.         public  _Line
  329. _Line proc
  330. ARG X1:WORD, Y1:WORD, X2:WORD, Y2:WORD, COLOR:WORD
  331.         push    bp
  332.         mov     bp,sp
  333.         push    ds
  334.  
  335.         mov     ax,@data
  336.         mov     ds,ax
  337.  
  338.         mov     es,_ModeX_Segment
  339.         push    si
  340.         push    di
  341.  
  342.         mov     ax,_Virtual_Width_Addr
  343.         mov        byte ptr cs:mod_3+2,al
  344.         mov        byte ptr cs:mod_6+2,al
  345.  
  346.         mov     ax,X1
  347.         sub     ax,X2           ; compute ax=DX=|X1-X2|
  348.         jge     short line_1
  349.         neg     ax
  350. line_1:
  351.         mov     si,Y1
  352.         sub     si,Y2           ; compute si=DY=|Y1-Y2|
  353.         jge     short line_2
  354.         neg     si
  355. line_2:
  356.         cmp     si,ax
  357.         jle     line_small_slope
  358.         jmp     line_big_slope
  359.  
  360. line_small_slope:               ; DX>=DY
  361.         mov     cx,si           ; cx=DY
  362.         shl     si,1            ; si=2DY
  363.         mov     cs:(mod_1-2),si ; CONST1=2DY>=0 (need segment override?)
  364.         sub     cx,ax           ; cx=DY-DX
  365.         shl     cx,1            ; cx=2(DY-DX)
  366.         mov     cs:(mod_2-2),cx ; CONST2=2(DY-DX)<=0
  367.         sub     si,ax           ; parameter si=P=2DY-DX
  368.  
  369.         mov     di,X1           ; these should probably go at the top where
  370.         mov     bx,X2           ;  X1,X2 are first loaded from the stack
  371.         cmp     di,bx
  372.         jl      short line_3    ;
  373.         mov     di,bx           ; X1>X2, so di has starting x value (X2)
  374.         mov     bx,Y2           ; bx has starting y value (Y2)
  375.         cmp     bx,Y1
  376.         jl      line_2_add_y
  377.         mov     word ptr cs:mod_3,0EF83h ; Hex for sub di,(immediate)
  378.         jmp     short line_2_3_again
  379. line_2_add_y:
  380.         mov     word ptr cs:mod_3,0C783h ; Hex for add di,(immediate)
  381.         jmp     short line_2_3_again
  382. line_3:                         ; X1<X2, so di has starting x value (X1)
  383.         mov     bx,Y1           ; bx has starting y value (Y1)
  384.         cmp     bx,Y2
  385.         jl      line_3_add_y
  386.         mov     word ptr cs:mod_3,0EF83h ; Hex for sub di,(immediate)
  387.         jmp     short line_2_3_again
  388. line_3_add_y:
  389.         mov     word ptr cs:mod_3,0C783h ; Hex for add di,(immediate)
  390. line_2_3_again:
  391.         shl     bx,1            ; index into big RowOffset table to get
  392.         mov     bx,word ptr _RowOffset[bx] ; scan line address
  393.         mov     cx,di           ; save X for computation of MapMask
  394.         shr     di,2            ; add offset (X/4) of pixel in scan line
  395.         add     di,bx           ; and store in di
  396.         mov     bx,ax           ; save count DX
  397.  
  398.                                 ; Our story so far:
  399.                                 ;  si = P
  400.                                 ;  bx = DX
  401.                                 ;  ax = DX
  402.                                 ;  cx = min(X1,X2)
  403.                                 ;  di = pixel address
  404.                                 ;  dx = ?
  405.  
  406.         and     cl,011b         ; cl = pixel's plane
  407.         mov     ax,1100h+MAP_MASK ; al = index in SC of Map Mask reg
  408.         shl     ah,cl           ; set only the bit for the pixel's plane to 1
  409.  
  410.         mov     cx,bx           ; restore count to cx
  411.         mov     dx,SC_INDEX     ; set the Map Mask to enable only
  412.                                 ;   the pixel's plane
  413.         mov     bl,byte ptr COLOR
  414.         jmp     short line_set_pixel
  415.  
  416. line_loop1:
  417.         rol     ah,1            ; next x
  418.         adc     di,0
  419.         cmp     si,0
  420.         jge     line_neg_p1
  421.  
  422.         add     si,2112h        ; next p
  423.                                 ;  SELF-MODIFYING (replace 0000 with CONST1)
  424. mod_1   label   word            ; label for modification
  425.  
  426.         jmp     short line_set_pixel
  427. mod_3   label   word
  428. line_neg_p1:
  429.         add     di,80           ; next y (add or subtract row width)
  430.                                 ;  SELF-MODIFYING (add/sub)
  431.  
  432.         add     si,4269h        ; next p
  433.                                 ;  SELF-MODIFYING (replace 0000 with CONST2)
  434. mod_2   label   word            ; label for modification
  435.  
  436. line_set_pixel:
  437.         out     dx,ax
  438.         mov     es:[di],bl      ; set the pixel (no segment override?)
  439.         dec     cx
  440.         jge     line_loop1
  441.  
  442.         jmp     line_done
  443.  
  444.  
  445. line_big_slope:                 ; DY>DX
  446.         mov     bx,ax           ; bx=DX
  447.         shl     ax,1            ; ax=2DX
  448.         mov     cs:(mod_4-2),ax ; CONST1=2DX>=0
  449.         mov     dx,si           ; dx=DY
  450.         shl     si,1            ; si=2DY
  451.         sub     ax,si           ; ax=2(DX-DY)
  452.         mov     cs:(mod_5-2),ax ; CONST2=2(DX-DY)<=0
  453.         mov     si,ax           ; si=2DX-2DY
  454.         add     si,dx           ; si=P=2DX-DY
  455.  
  456.         mov     di,X1           ; these should probably go at the top where
  457.         mov     bx,X2           ;  X1,X2 are first loaded from the stack
  458.         cmp     di,bx
  459.         jl      short line_6    ;
  460.         mov     di,bx           ; X1>=X2, so di has starting x value (X2)
  461.         mov     bx,Y2           ; bx has starting y value (Y2)
  462.         cmp     bx,Y1
  463.         jl      line_5_add_y
  464.         mov     word ptr cs:mod_6,0EF83h ; Hex for sub di,(immediate)
  465.         jmp     short line_5_6_again
  466. line_5_add_y:
  467.         mov     word ptr cs:mod_6,0C783h ; Hex for add di,(immediate)
  468.         jmp     short line_5_6_again
  469. line_6:                         ; X1<X2, so di has starting x value (X1)
  470.         mov     bx,Y1           ; bx has starting y value (Y1)
  471.         cmp     bx,Y2
  472.         jl      line_6_add_y
  473.         mov     word ptr cs:mod_6,0EF83h ; Hex for sub di,(immediate)
  474.         jmp     short line_5_6_again
  475. line_6_add_y:
  476.         mov     word ptr cs:mod_6,0C783h ; Hex for add di,(immediate)
  477. line_5_6_again:
  478.         shl     bx,1            ; index into big RowOffset table to get
  479.         mov     bx,word ptr _RowOffset[bx] ; scan line address
  480.         mov     cx,di           ; save X for computation of MapMask
  481.         shr     di,2            ; add offset (X/4) of pixel in scan line
  482.         add     di,bx           ; and store in di
  483.  
  484.                                 ; Our story so far:
  485.                                 ;  si = P
  486.                                 ;  bx = address
  487.                                 ;  ax = CONST2
  488.                                 ;  cx = DY
  489.                                 ;  di = pixel address
  490.                                 ;  dx = DY
  491.  
  492.         and     cl,011b         ; cl = pixel's plane
  493.         mov     ax,1100h+MAP_MASK ; al = index in SC of Map Mask reg
  494.         shl     ah,cl           ; set only the bit for the pixel's plane to 1
  495.  
  496.         mov     cx,dx           ; restore count to cx
  497.  
  498.         mov     bl,byte ptr COLOR
  499.         mov     dx,SC_INDEX     ; set the Map Mask to enable only
  500.                                 ;  the pixel's plane
  501.         jmp     short line_loop_enter_2
  502.  
  503. mod_6   label   word
  504. line_loop2:
  505.         add     di,80           ; next y (add or subtract row width)
  506.                                 ;  SELF-MODIFYING (add/sub)
  507.         cmp     si,0
  508.         jge     line_neg_p2
  509.         add     si,2001         ; next p
  510.                                 ;  SELF-MODIFYING (replace 0000 with CONST1)
  511. mod_4   label   word            ; label for modification
  512.         jmp     short line_set_pixel2
  513. line_neg_p2:
  514.         rol     ah,1            ; next x
  515.         adc     di,0
  516.         add     si,0Bach        ; next p
  517.                                 ;  SELF-MODIFYING (replace 0000 with CONST2)
  518. mod_5   label   word            ; label for modification
  519. line_loop_enter_2:
  520.         out     dx,ax
  521. line_set_pixel2:
  522.         mov     es:[di],bl      ; set the pixel
  523.         dec     cx
  524.         jge     line_loop2
  525.  
  526. line_done:
  527.         pop     di      ; restore caller's register variables
  528.         pop     si
  529.         pop     ds
  530.         pop     bp      ; restore caller's stack frame
  531.         ret
  532. _Line   endp
  533.  
  534.  
  535.  
  536. ;----------------------------------------------------------------------------
  537. END